package tema1;

public class DecisionTree {
	private DataSet dataSet;
	private Node rootNode;
	private SymbolicValue defaultValue;
	
	public DecisionTree(DataSet dataSet) {
		if (dataSet == null)
			throw new IllegalArgumentException("Empty data set");
		
		this.dataSet = dataSet;
		this.defaultValue = this.dataSet.findDefaultValue();
		
		rootNode = build(this.dataSet, null);
	}
	
	private Node build(DataSet dataSet, AttributeValue branchValue) {
		SymbolicValue homogenousValue = dataSet.getHomogenousValue();
		if (homogenousValue != null)
			return new LeafNode(homogenousValue, branchValue);
		
		if (dataSet.getAttributeSet().size() == 0)
			return new LeafNode(defaultValue, branchValue);
		
		
		Attribute splitAttribute = dataSet.findBestSplit();
		
		if (splitAttribute == null)
			return new LeafNode(defaultValue, branchValue);
		
		BranchNode node = new BranchNode(splitAttribute, branchValue);
		
		DataSet[] splitDataSets = dataSet.split(splitAttribute);
		
		for (int i = 0; i < splitDataSets.length; i++) {
			DataSet splitDataSet = splitDataSets[i];
			SymbolicAttribute symbolicSplitAttribute = (SymbolicAttribute) splitAttribute;
			if (splitDataSet.isEmpty())
				node.addChild(new LeafNode(defaultValue, symbolicSplitAttribute.getValue(i)));
			else
				node.addChild(build(splitDataSet, symbolicSplitAttribute.getValue(i)));
		}
		
		return node;
	}
	
	private void printTree(Node root, String lines) {
		if (root instanceof BranchNode) {
			BranchNode branchRoot = (BranchNode) root;
			
			for (Node childNode : branchRoot.getChildren()) {
				if (childNode instanceof BranchNode) {
					BranchNode branchNode = (BranchNode) childNode;
					System.out.println(lines + branchRoot.getAttribute() + " = " + branchNode.getBranchValue());
					printTree(childNode, lines + "| ");
				} else
					if (childNode instanceof LeafNode) {
						LeafNode leafNode = (LeafNode) childNode;
						System.out.println(lines + branchRoot.getAttribute() + " = " + leafNode.getBranchValue() + ": " + leafNode.getClassValue());
					}
			}
		}
	}
	
	public void printTree() {
		System.out.println("Default value: " + defaultValue);
		printTree(rootNode, "");
	}
}
